#ifndef SKYROAD_REQUEST_PARSER_H_
#define SKYROAD_REQUEST_PARSER_H_

#include <boost/logic/tribool.hpp>
#include <boost/tuple/tuple.hpp>
#include <boost/format.hpp>


struct request;
/// Parser for incoming requests.
class request_parser
{
public:
	/// Construct ready to parse the request method.
	request_parser();

	/// Reset to initial parser state.
	void reset();

	/// Parse some data. The tribool return value is true when a complete request
	/// has been parsed, false if the data is invalid, indeterminate when more
	/// data is required. The InputIterator return value indicates how much of the
	/// input has been consumed.
	template <typename InputIterator>
		boost::tuple<boost::tribool, InputIterator> parse(request& req,
		InputIterator begin, InputIterator end)
	{
		while (begin != end)
		{
			boost::tribool result = consume(req, *begin++);
			if (result || !result)
				return boost::make_tuple(result, begin);
		}
		boost::tribool result = boost::indeterminate;
		return boost::make_tuple(result, begin);
	}

private:
	/// Handle the next character of input.
	boost::tribool consume(request& req, char input);

	/// Check if a byte is an HTTP character.
	static bool is_char(int c);

	/// Check if a byte is an HTTP control character.
	static bool is_ctl(int c);

	/// Check if a byte is defined as an HTTP tspecial character.
	static bool is_tspecial(int c);

	/// Check if a byte is a digit.
	static bool is_digit(int c);

	/// The current state of the parser.
	enum state
	{
		method_start,
		method,
		uri_start,
		uri,
		version_h,
		version_t_1,
		version_t_2,
		version_p,
		version_slash,
		version_major_start,
		version_major,
		version_minor_start,
		version_minor,
		expecting_newline_1,
		header_line_start,
		header_lws,
		header_name,
		space_before_header_value,
		header_value,
		expecting_newline_2,
		expecting_newline_3,
		content
	} state_;

	int content_size_;

};

#endif

 

